using System.ComponentModel.DataAnnotations;
using OneCaps.Core.Enum;
using OneCaps.Core.Models;

namespace OneCaps.Core.Entity
{
    /// <summary>
    /// 收费规则实体
    /// </summary>
    public class BillingRule : BaseEntity<int>
    {
        /// <summary>
        /// 规则名称
        /// </summary>
        [Required]
        [MaxLength(100)]
        public string Name { get; set; } = string.Empty;

        /// <summary>
        /// 规则描述
        /// </summary>
        [MaxLength(500)]
        public string? Description { get; set; }

        /// <summary>
        /// 适用车辆类型
        /// </summary>
        public VehicleType VehicleType { get; set; } = VehicleType.Private;

        /// <summary>
        /// 适用车位类型
        /// </summary>
        public ParkingSpaceType? ParkingSpaceType { get; set; }

        /// <summary>
        /// 是否VIP规则
        /// </summary>
        public bool IsVipRule { get; set; } = false;

        /// <summary>
        /// 免费时长（分钟）
        /// </summary>
        public int FreeMinutes { get; set; } = 0;

        /// <summary>
        /// 首小时费率
        /// </summary>
        public decimal FirstHourRate { get; set; } = 0;

        /// <summary>
        /// 后续小时费率
        /// </summary>
        public decimal SubsequentHourRate { get; set; } = 0;

        /// <summary>
        /// 每日最高收费
        /// </summary>
        public decimal? DailyMaxFee { get; set; }

        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnabled { get; set; } = true;

        /// <summary>
        /// 生效时间
        /// </summary>
        public DateTime EffectiveTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 失效时间
        /// </summary>
        public DateTime? ExpiryTime { get; set; }

        /// <summary>
        /// 优先级（数字越大优先级越高）
        /// </summary>
        public int Priority { get; set; } = 1;

        /// <summary>
        /// 特殊时段规则
        /// </summary>
        public virtual ICollection<SpecialTimeRule> SpecialTimeRules { get; set; } = new List<SpecialTimeRule>();

        // 领域方法
        /// <summary>
        /// 检查规则是否有效
        /// </summary>
        public bool IsValid()
        {
            if (!IsEnabled) return false;
            
            var now = DateTime.Now;
            if (now < EffectiveTime) return false;
            if (ExpiryTime.HasValue && now > ExpiryTime.Value) return false;
            
            return true;
        }

        /// <summary>
        /// 计算停车费用
        /// </summary>
        public Money CalculateFee(TimeSpan parkingDuration)
        {
            if (!IsValid())
            {
                throw new InvalidOperationException("收费规则无效");
            }

            var totalMinutes = (int)parkingDuration.TotalMinutes;
            
            // 免费时长
            if (totalMinutes <= FreeMinutes)
            {
                return new Money(0);
            }

            var chargeableMinutes = totalMinutes - FreeMinutes;
            var hours = (int)Math.Ceiling(chargeableMinutes / 60.0);

            decimal fee;
            if (hours <= 1)
            {
                fee = FirstHourRate;
            }
            else
            {
                fee = FirstHourRate + (hours - 1) * SubsequentHourRate;
            }

            // 应用每日最高收费限制
            if (DailyMaxFee.HasValue && fee > DailyMaxFee.Value)
            {
                fee = DailyMaxFee.Value;
            }

            return new Money(fee);
        }

        /// <summary>
        /// 检查是否适用于指定车辆和车位
        /// </summary>
        public bool IsApplicable(VehicleType vehicleType, ParkingSpaceType? spaceType = null)
        {
            if (VehicleType != vehicleType) return false;
            if (ParkingSpaceType.HasValue && spaceType.HasValue && ParkingSpaceType.Value != spaceType.Value) return false;
            return true;
        }
    }

    /// <summary>
    /// 特殊时段规则
    /// </summary>
    public class SpecialTimeRule : BaseEntity<int>
    {
        /// <summary>
        /// 开始时间
        /// </summary>
        public TimeSpan StartTime { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public TimeSpan EndTime { get; set; }

        /// <summary>
        /// 特殊费率
        /// </summary>
        public decimal SpecialRate { get; set; }

        /// <summary>
        /// 适用星期（1-7，1=周一）
        /// </summary>
        public int? DayOfWeek { get; set; }

        /// <summary>
        /// 所属收费规则
        /// </summary>
        public int BillingRuleId { get; set; }
        public virtual BillingRule BillingRule { get; set; } = null!;
    }
} 